/*
 ----------------------------------------------------------------------------------
                          "THE BEER-WARE COPYRIGHT LICENSE"
                                    (Revision 43)
                                     -----------
   Rymek [rymek@rymek.org] wrote this file. As long as You retain this notice and
   this file has been sent directly to You by the author, You can do whatever You
   want with this stuff as long as You don't sell or rent it. If we meet some day,
   and You think this stuff is worth it, You can buy me a beer in return :-)
                                                                __________
                                                                Paweł Rymaszewski
 ----------------------------------------------------------------------------------
 */

package processing.logic.util;

import constants.Constants;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;

import java.io.IOException;
import java.io.StringWriter;
import java.util.zip.DataFormatException;
import java.util.zip.Inflater;

/**
 * Class for decoding Oracle BLOB datatypes (XML messages are stored
 * as BLOB fields in database) into Java String objects
 *
 * @author rymek
 *         User: rymek
 *         Date: 30.06.11
 *         Time: 10:10
 */
public class Decoder {

    /**
     * Method for decoding XML messages stored as blobs in database
     *
     * @param resultLength     length of the BLOB database field
     * @param compressedResult binary data stored in the BLOB database field
     * @return string representing message XML body
     * @throws DataFormatException thrown when Data format is invalid
     * @throws DocumentException   thrown when Document exception is found
     * @throws IOException         thrown when I/O error occurs
     */
    public String Decode(byte[] compressedResult, int resultLength)
            throws DataFormatException, DocumentException, IOException {

        Inflater inflater = new Inflater();

        byte[] uncompressedResult = new byte[resultLength];
        inflater.setInput(compressedResult);                           // XML messages need to be inflated before processed hence inflating results
        int uncompressedLength = inflater.inflate(uncompressedResult); // uncompressed message length
        inflater.end();

        String decodedMessage = new String(uncompressedResult, 0,
                uncompressedLength, Constants.DB_TEXT_ENCODING);       // decodes message to specified database models encoding

        return this.formatMessage(decodedMessage);                     // returns string representing XML message body
    }

    /**
     * Method formats given XML string into proper XML formatted string
     *
     * @param message Message to format
     * @return string representing message XML body
     * @throws DocumentException thrown when Document exception is found
     * @throws IOException       thrown when I/O error occurs
     */
    public String formatMessage(String message) throws DocumentException, IOException {

        OutputFormat format = OutputFormat.createPrettyPrint();        // creates formatter that formats output string
        StringWriter stringWriter = new StringWriter();                // creates string writer that will be used to generate output string
        XMLWriter xmlWriter = new XMLWriter(stringWriter, format);     // creates XML writer
        Document xmlDoc = DocumentHelper.parseText(message);           // formats output string to XML format
        xmlWriter.write(xmlDoc);                                       // writes XML body to StringWriter object

        return stringWriter.toString();                                // returns string representing XML message body
    }
}
